/*
todo
 1. 新增是否顯示 title (ex:<com.delta.vd.commons.dao.SQLMaker>$printSQL) 的方法，SQLMaker 太熟了不要前面那段比較好看。
 2. 新增是否顯示日期的方法。(也許都用 logger 就不用考慮了，日期由 logger 決定處理?)

2012-11-08 by jieh
 1. 修改 debug mode 與 log4j 整合
*/
package idv.jieh.commons.util;

import org.apache.commons.logging.*;

public class DeBuger implements java.io.Serializable {

  private static final long serialVersionUID = -4383013054186819738L;

//  private static final boolean d = true;

  private static Log log = LogFactory.getLog(DeBuger.class);

  // 加冠後的物件名稱。
  private String tn;
  // 加冠後的方法名稱。
  private String tm = "";

  public DeBuger() {
    this("No Defined Object Name");
  }


  // 可設定物件名稱，列印訊息時方便辨識。
  public DeBuger(String name) {
    this.setName(name);
 }

  private static final Throwable throwable = new Throwable();
  /**
   * 取得目前程式執行到 Java Code 中的第幾行。
   * @return int 程式碼行號。
   */
  public static synchronized int getLineNumberInCode() {
    throwable.fillInStackTrace();
    StackTraceElement[] elements = throwable.getStackTrace();
    return (elements == null || elements.length <= 1) ? -1 : elements[1].getLineNumber();
  }

  /**
   * 詢問 DeBuger 目前的除錯狀態。<p>
   * @return true：除錯模式開啟；false：除錯模式關閉。
   */
  public static boolean isDebug() {
    return log.isDebugEnabled();
//    return d;
  }


  // 設定物件名稱。
  public void setName(String s) {
    tn = "<".concat(s).concat(">");
  }

  // 設定方法名稱。
  public void setMethodName(String s) {
    tm = "$".concat(s);
  }

  // 列印例外訊息。
  public void exception(Exception e) {
    log.error(tn, e);

//    StringBuilder sb = new StringBuilder();
//    sb.append("\n").append(showTitle());
//    sb.append("*********************************** Exception Start ***********************************");
//    sb.append(e.getMessage());
//    this.print("");
//    this.showTitle();
//    this.print(
//        "*********************************** Exception Start ***********************************");
//    e.printStackTrace(System.out);
//    this.print(
//        "***********************************  Exception End  ***********************************");
//    this.print("");
  }

  // 列印例外訊息並停止程式執行。
  public void exceptionAndExit(Exception e){
    exception(e);
    System.exit(-1);
  }

  // 列印一般資訊。
  public void normal(String msg) {
//    StringBuilder sb = this.showTitle();
//    log.info(sb.append(msg).toString());
    log.info(msg);
  }

  /**
   * 列印除錯訊息。<p>
   * 使用時分別輸入這個訊息是由哪個方法提出列印要求。<br>
   * 第二個參數放入要列印的訊息。<br>
   * 如果除錯模式開啟的話，這個方法會將輸入的資訊列印出來，反之則不會。
   * @param name 方法名稱。
   * @param msg 要列印的訊息。
   */
  public void debug(String name, String msg) {
    log.debug(msg);
    /*
    if (d) {
      this.setMethodName(name);
      this.normal(msg);
    }
    */
  }

//  private void print(String s) { System.out.println(s); }

  // 顯示開頭訊息...
  private StringBuilder showTitle() {
    CurrentDate cd = new CurrentDate();
    StringBuilder sb = new StringBuilder();
    sb.append("[").append(cd.getLocalCrntDate("/"));
    sb.append(" ").append(cd.getCrntTime(":", true)).append("]");
    sb.append(tn).append(tm).append(" : ");
//    this.print(sb.toString());
    return sb;
  }

} // end class
